from flask import Flask, render_template, jsonify, request, redirect, url_for, session
from flask_mail import Mail, Message
import random
from db_model import ToConn
from werkzeug.security import check_password_hash, generate_password_hash
import datetime
from werkzeug.middleware.proxy_fix import ProxyFix
import functools


"""创建app"""
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.139.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'your_email@139.com'
app.config['MAIL_PASSWORD'] = 'password'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
app.config['SECRET_KEY'] = 'fdabfdadsghdfasfda'
app.wsgi_app = ProxyFix(app.wsgi_app)


def login_required(view):
    """限制没有登录的访问"""
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if session.get('user_email') is None:
            return redirect(url_for('login'))
        return view(**kwargs)

    return wrapped_view


@app.route('/')
@login_required
def index():
    """主页"""
    return render_template('index.html')


@app.route('/login', methods=('GET', 'POST'))
def login():
    """登录"""
    if request.method == 'POST':
        email = request.form.get('email')
        password = request.form.get('password')
        conn = ToConn().get_db('select email,password,update_time from users where email=%s and is_locked=0', (email,))
        result = conn.fetchone()
        # print(result)
        if result and check_password_hash(result.get('password'), password):
            # 获取用户登录ip，并且注册session
            # print(request.remote_addr)
            conn = ToConn().to_execute()
            cur = conn.cursor()
            update_res = cur.execute('update users set login_ip=%s where email=%s', (request.remote_addr, email))
            cur.execute('insert into users_login_ip(user_email, login_ip) value (%s,%s)', (email, request.remote_addr))
            conn.commit()
            session.clear()
            session['user_email'] = result.get('email')
            return redirect(url_for('index'))
        elif result and not check_password_hash(result.get('password'), password):
            # 密码错误
            if datetime.datetime.now().minute-result.get('update_time').minute<10:
                conn = ToConn().to_execute()
                cur = conn.cursor()
                update_res = cur.execute('update users set is_locked=1 where email=%s', (email,))
                conn.commit()
                return '连续操作密码错误，账户已锁住，请联系管理员！'
            else:
                conn = ToConn().to_execute()
                cur = conn.cursor()
                update_res = cur.execute('update users set update_time=now() where email=%s', (email,))
                conn.commit()
                return '账户或密码错误，请重试！'
        else:
            return '账户不存在，请先注册；或账户已冻结，请联系管理员！'
    return render_template('login.html')


@app.route('/logout', methods=('GET',))
@login_required
def logout():
    """退出登录"""
    session.clear()
    return redirect(url_for('index'))


@app.route('/logoutTime', methods=('POST',))
@login_required
def logoutTime():
    """无操作自动退出登录"""
    # user_email = request.form.get('user_mail')
    # print(user_email)
    session.pop('user_email')
    return jsonify({'result': 1})


@app.route('/register', methods=('GET',))
def register():
    """注册"""
    # if request.method == 'POST':
    #     email = request.form.get('email')
    #     code = request.form.get('code')
    #     password = request.form.get('password')
    #     password2 = request.form.get('password2')
    #     conn = ToConn().get_db('select code,time from mail_code where email=%s', (email,))
    #     result = conn.fetchone()
    #
    #     try:
    #         if result and datetime.datetime.now().second - result.get('time').second <= 5 and str(
    #                 result['code']) == code and password == password2:
    #             time = result.get('time')
    #             # print(datetime.datetime.now().second, type(time.second))
    #             # 加密写入数据库
    #             conn = ToConn().to_execute()
    #             cur = conn.cursor()
    #             result = cur.execute('insert into users(email, password) value (%s,%s)',
    #                                  (email, generate_password_hash(password)))
    #             if result:
    #                 conn.commit()
    #                 return redirect(url_for('login'))
    #             else:
    #                 conn.rollback()
    #                 return '注册提交失败，请重试！'
    #         else:
    #             return '注册失败，密码或验证码错误，请重试！'
    #     except Exception as e:
    #         print('注册错误！', e)
    #         return '注册失败，请重试！'
    # GET 方法
    return render_template('register.html')


@app.route('/reg', methods=('POST',))
def reg():
    email = request.form.get('email')
    code = request.form.get('code')
    password = request.form.get('password')
    password2 = request.form.get('password2')

    conn = ToConn().get_db('select code,time from mail_code where email=%s', (email,))
    result = conn.fetchone()

    try:
        if result and datetime.datetime.now().second - result.get('time').second <= 5 and str(
                result['code']) == code and password == password2:
            time = result.get('time')
            # print(datetime.datetime.now().second, type(time.second))
            # 加密写入数据库
            conn = ToConn().to_execute()
            cur = conn.cursor()
            result = cur.execute('insert into users(email, password) value (%s,%s)',
                                 (email, generate_password_hash(password)))
            if result:
                conn.commit()
                return {'result': 1}
            else:
                conn.rollback()
                return {'result': 0}
        else:
            return {'result': 0}
    except Exception as e:
        print('注册错误！', e)
        return {'result': 0}


@app.route('/register/get_email', methods=('POST',))
def get_email():
    """验证邮箱"""
    user_mail = request.form.get('user_mail')
    # 查询是否已经注册
    conn3 = ToConn().get_db('select email from users where email=%s', (user_mail,))
    user_res = conn3.fetchone()
    if user_res:
        return jsonify({"result": 2})
    code = random.randint(100000, 999999)
    msg = Message('科技-注册邮箱验证', sender='your_email@139.com', recipients=[user_mail])
    msg.body = "您的账号正在关联邮箱，邮箱验证码为："+str(code)
    mail.send(msg)
    # 将验证码写入数据库
    conn1 = ToConn().get_db('select code from mail_code where email=%s', (user_mail,))
    result = conn1.fetchone()
    conn2 = ToConn().to_execute()
    cur = conn2.cursor()
    if result:
        result = cur.execute('update mail_code set code=%s where email=%s', (code, user_mail))
    else:
        result = cur.execute('insert into mail_code(email, code) value (%s,%s)', (user_mail, code))
    if result:
        conn2.commit()
        return jsonify({"result": 1})
    else:
        conn2.rollback()
        return jsonify({"result": 0})


if __name__ == '__main__':
    app.run()
